package com.jiexin.service;

import com.google.common.base.Preconditions;
import com.jiexin.common.RequestHolder;
import com.jiexin.dao.SysAclMapper;
import com.jiexin.dao.SysAclModuleMapper;
import com.jiexin.exception.ParamException;
import com.jiexin.model.SysAclModule;
import com.jiexin.model.SysDept;
import com.jiexin.param.AclModuleParam;
import com.jiexin.param.DeptParam;
import com.jiexin.util.BeanValidator;
import com.jiexin.util.IpUtil;
import com.jiexin.util.LevelUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @Author: Jay_Liu
 * @Description: 权限模块逻辑处理
 * @Date: Created in 13:35 2018/4/8 0008
 * @Modified By:
 */
@Service
public class SysAclModuleService {

    @Resource
    private SysAclModuleMapper sysAclModuleMapper;

    @Resource
    private SysAclMapper sysAclMapper;

    @Resource
    private SysLogService sysLogService;

    //保存
    public void save(AclModuleParam param){
        BeanValidator.check(param);
        if(checkExist(param.getParentId(), param.getName(), param.getId())) {
            throw new ParamException("同一层级存在相同名称的权限模块名称");
        }
        //建造者方式创建对象
        SysAclModule aclModule = SysAclModule.builder().name(param.getName()).parentId(param.getParentId())
                .seq(param.getSeq()).status(param.getStatus()).remark(param.getRemark()).build();
        //设置部门等级
        aclModule.setLevel(LevelUtil.calculateLevel(getLevel(aclModule.getParentId()), aclModule.getParentId()));
        //获取当前线程中的用户信息
        aclModule.setOperator(RequestHolder.getCurrentUser().getUsername());
        //根据请求获取IP
        aclModule.setOperateIp(IpUtil.getRemoteIp(RequestHolder.getCurrentRequest()));
        aclModule.setOperateTime(new Date());
        sysAclModuleMapper.insertSelective(aclModule);
        sysLogService.saveAclModuleLog(null, aclModule);
    }

    //更新
    public void update(AclModuleParam param){
        BeanValidator.check(param);
        if(checkExist(param.getParentId(), param.getName(), param.getId())) {
            throw new ParamException("同一层级存在相同名称的权限模块名称");
        }
        //附加程序：04.18
        if(param.getParentId() == param.getId()) {
            throw new ParamException("不允许移动到权限模块本身的下属模块");
        }
        SysAclModule before = sysAclModuleMapper.selectByPrimaryKey(param.getId());
        Preconditions.checkNotNull(before, "待更新的权限模块不存在");
        SysAclModule after = SysAclModule.builder().id(param.getId()).name(param.getName()).parentId(param.getParentId())
                .seq(param.getSeq()).status(param.getStatus()).remark(param.getRemark()).build();
        after.setLevel(LevelUtil.calculateLevel(getLevel(param.getParentId()),param.getParentId()));
        //获取当前线程中的用户信息
        after.setOperator(RequestHolder.getCurrentUser().getUsername());
        //根据请求获取IP
        after.setOperateIp(IpUtil.getRemoteIp(RequestHolder.getCurrentRequest()));
        after.setOperateTime(new Date());
        updateWithChild(before, after);
        sysLogService.saveAclModuleLog(before, after);
    }

    //更新权限模块
    @Transactional
    public void updateWithChild(SysAclModule before, SysAclModule after) {

        String newLevelPrefix = after.getLevel();
        String oldLevelPrefix = before.getLevel();
        if(!after.getLevel().equals(before.getLevel())) {
            //通过部门等级获取所有子部门
            //原程序:
            //List<SysAclModule> aclModuleList = sysAclModuleMapper.getChildAclModuleListByLevel(before.getLevel());
            //附加程序：04.18 ：获取当前权限模块所有子权限模块(当前等级+当前ID = 下级模块等级的前缀)
            List<SysAclModule> aclModuleList = sysAclModuleMapper.getChildAclModuleListByLevel(LevelUtil.calculateLevel(before.getLevel(),before.getId()));
            if(CollectionUtils.isNotEmpty(aclModuleList)) {
                for (SysAclModule aclModule : aclModuleList) {
                    //旧的level
                    String level = aclModule.getLevel();
                    //若是以旧level前缀的，则更新level
                    if (level.indexOf(oldLevelPrefix) == 0) {
                        //拼接新的level
                        level = newLevelPrefix + level.substring(oldLevelPrefix.length());
                        aclModule.setLevel(level);
                    }
                }
                //批量更新子部门的level
                sysAclModuleMapper.batchUpdateLevel(aclModuleList);
            }
        }
        //最后更新
        sysAclModuleMapper.updateByPrimaryKey(after);

    }

    //校验同一级下不能出现相同的权限模块名称
    private boolean checkExist(Integer parentId, String aclModuleName, Integer aclModuleId){
        return sysAclModuleMapper.countByNameAndParentId(parentId, aclModuleName, aclModuleId) > 0;
    }

    //根据权限模块id找到权限模块等级
    private String getLevel(Integer aclModuleId) {
        SysAclModule sysAclModule = sysAclModuleMapper.selectByPrimaryKey(aclModuleId);
        if (sysAclModule == null) {
            return null;
        }
        return sysAclModule.getLevel();
    }

    public void delete(int aclModuleId) {
        SysAclModule sysAclModule = sysAclModuleMapper.selectByPrimaryKey(aclModuleId);
        Preconditions.checkNotNull(sysAclModule,"删除的权限模块不存在");
        //查看当前权限模块下是否有子权限模块
        if(sysAclModuleMapper.countByParentId(aclModuleId) > 0 ){
            throw new ParamException("当前权限模块下有子权限模块,无法删除");
        }
        //查看当前权限模块下是否有权限点
        if(sysAclMapper.countByaclModuleId(aclModuleId) > 0){
            throw new ParamException("当前权限模块下有权限点,无法删除");
        }
        //删除
        sysAclModuleMapper.deleteByPrimaryKey(aclModuleId);
    }
}
